function numberToWords(num: number): string {
    if (num === 0) return "Zero";
    
    let xs = [  
        { div: 1000000000, label: "Billion" },
        { div: 1000000, label: "Million" },
        { div: 1000, label: "Thousand" },
        { div: 1, label: "Hundred" },
    ]

    let _1_to_9 = ["", "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine"]
    let _10_to_19 =  ["Ten", "Eleven", "Twelve", "Thirteen", "Fourteen", "Fifteen", "Sixteen", "Seventeen", "Eighteen", "Nineteen"]
    let dozens = ["", "", "Twenty", "Thirty", "Forty", "Fifty", "Sixty", "Seventy", "Eighty", "Ninety"]

    var answer = new Array<string>();
    for(var x of xs) {
        var whole = Math.floor(num / x.div)
        var reminder = num % x.div
        if (whole === 1 && reminder === 0 && num >= 1000) 
            answer.push("One", x.label);
        else if (whole > 0) {
            var hundreds = Math.floor(whole / 100)
            if (hundreds > 0) answer.push( _1_to_9[hundreds], "Hundred")
            let moduloOf100 = whole % 100;
            if (moduloOf100 >= 10 && moduloOf100 <= 19) answer.push( _10_to_19[moduloOf100 - 10])
            else {
                answer.push( dozens[ Math.floor( moduloOf100 / 10) ])
                answer.push( _1_to_9[moduloOf100 % 10])
            }
            if (x.div > 1) 
                answer.push( x.label)
        }
        num = reminder;
    }

    var temp = answer.filter(x => x !== "").join(' ');
    return answer.filter(x => x !== "").join(' ');
};

console.assert(numberToWords(2000) === "Two Thousand");
console.assert(numberToWords(0) === "Zero");
console.assert(numberToWords(1) === "One");
console.assert( numberToWords(123) === "One Hundred Twenty Three")
console.assert( numberToWords(12345) === "Twelve Thousand Three Hundred Forty Five")
console.assert( numberToWords(1234567) === "One Million Two Hundred Thirty Four Thousand Five Hundred Sixty Seven")